import sys
import xlrd 
import datetime

class ReadError(Exception):
    pass

def convert_value(_type, value, encoding, book):
    if _type == 1:  #XL_CELL_TEXT
        if encoding is not None:
            return value.encode(encoding)
        else:
            return value
    elif _type == 3:
        d = xlrd.xldate_as_tuple(value, book.datemode)
        return datetime.datetime(*d)
    else:
        return value
    
def open_book(filename=None, file_contents=None, fields=None, begin=0, sheet_index=0, log=None, encoding=None, converts=None):
    converts = converts or {}
    
    try:
        book = xlrd.open_workbook(filename=filename, file_contents=file_contents, on_demand=True)
    except Exception, e:
        if log:
            log.exception(e)
        raise ReadError, "Can't open the excel file %s" % filename
    sh = book.sheet_by_index(sheet_index)
    if not fields:
        fields = dict(zip(range(sh.ncols), range(sh.ncols)))
    
    for rx in range(begin, sh.nrows):
        line = {}
        try:
            for ry in fields.iterkeys():
                v = sh.cell_value(rx, ry)
                t = sh.cell_type(rx, ry)
                key = fields[ry]
                convert = converts.get(key, None)
                if convert:
                    v = convert(t, v, encoding, book)
                else:
                    v = convert_value(t, v, encoding, book)
                    
                line[key] = v
            yield line
        except Exception, e:
            if log:
                log.exception(e)
            raise ReadError, "Read Excel file %s error in line %d" % (filename, rx)

if __name__ == '__main__':
    f = open(sys.argv[1], 'rb')
    for line in open_book(sys.argv[1], f.read(), encoding='gbk'):
        print line